package com.bolehui.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bolehui.base.enums.JobStatusTypeEnum;
import com.bolehui.base.result.PageResult;
import com.bolehui.base.result.Result;
import com.bolehui.base.utils.LogUtil;
import com.bolehui.domain.dto.JobDTO;
import com.bolehui.domain.po.JobPO;
import com.bolehui.domain.vo.JobVO;
import com.bolehui.mapper.AreaMapper;
import com.bolehui.mapper.JobMapper;
import com.bolehui.service.JobService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author chendongjie     email:chendongjie@gz.iscas.ac.cn
 * @version 1.0
 * @ClassName JobServiceImpl
 * @Description
 * @createTime 2024/12/11 14:36
 * Copyright (C) 2021-2022 CASEEDER, All Rights Reserved.
 * 注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的
 */
@Service
public class JobServiceImpl extends ServiceImpl<JobMapper, JobPO> implements JobService {

    @Autowired
    private JobMapper jobMapper;
    @Autowired
    private AreaMapper areaMapper;

    /**
     * 查询所有职位
     *
     * @return
     */
    @Override
    public Result listJobs(Integer pageNum, Integer pageSize) {
        try {
            if (ObjectUtil.isNull(pageNum)) {
                pageNum = 1;
            }
            if (ObjectUtil.isNull(pageSize)) {
                pageSize = 10;
            }
            // 开始分页
            PageHelper.startPage(pageNum, pageSize);
            // 1. 使用LambdaQueryWrapper查询所有职位状态
            List<JobPO> jobStatusList = jobMapper.selectJobs(new LambdaQueryWrapper<>());

            // 2. 检查查询结果
            if (jobStatusList.isEmpty()) {
                log.warn("职位状态列表为空");
                return Result.success(Collections.emptyList(), "未找到职位状态信息");
            }
            // 使用 Stream API 将 JobPO 转换为 JobDTO
            List<JobDTO> jobDTOS = jobStatusList.stream()
                    .map(jobPO -> toJobDTO(jobPO, areaMapper))
                    .collect(Collectors.toList());
            PageInfo<JobDTO> pageInfo = new PageInfo<>(jobDTOS);
            // 创建 PageResult 对象
            PageResult<JobDTO> pageResult = new PageResult<>(pageInfo);
            // 3. 返回查询结果
            LogUtil.info(String.format("成功查询到 %d 条职位状态记录", jobStatusList.size()));
            return Result.success(pageResult);


        } catch (Exception e) {
            // 4. 捕获并处理异常
            log.error("查询职位状态列表异常", e);
            return Result.fail("查询职位状态列表失败，请稍后重试");
        }
    }


    /**
     * 发布职位
     *
     * @param id
     * @return
     */
    @Override
    public Result postJob(Long id) throws Exception {
        try {
            // 1. 直接更新职位状态
            UpdateWrapper<JobPO> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", id)
                    .set("job_status", JobStatusTypeEnum.Close);
            int updateCount = jobMapper.update(null, updateWrapper);
            // 2. 检查更新结果
            if (updateCount > 0) {
                return Result.success("职位发布成功");
            } else {
                return Result.fail("职位不存在或更新失败");
            }
        } catch (Exception e) {
            // 3. 捕获并处理异常
            return Result.fail("职位发布异常，请稍后重试");
        }
    }

    /**
     * 新增职位
     *
     * @param job
     * @return
     */
    @Override
    public Result save(JobVO job, Long userId) {
        try {
            // 1. 参数校验
            if (job == null || userId == null) {
                return Result.fail("参数不能为空");
            }

            // 2. 属性拷贝
            JobPO jobPO = new JobPO();
            BeanUtils.copyProperties(job, jobPO);
            jobPO.setUserId(userId);
            jobPO.setJobStatus(JobStatusTypeEnum.Posted);

            // 3. 插入数据
            int insertCount = jobMapper.insert(jobPO);
            // 4. 检查插入结果
            if (insertCount > 0) {
                return Result.success("职位保存成功");
            } else {
                return Result.fail("职位保存失败");
            }
        } catch (Exception e) {
            // 5. 捕获并处理异常
            return Result.fail("职位保存异常，请稍后重试");
        }
    }

    /**
     * 根据用户id获取对应的职位信息
     *
     * @param userId
     * @return
     */
    @Override
    public Result<PageResult<JobDTO>> getJobWithPage(Long userId, Integer pageNum, Integer pageSize) {
        // 参数校验
        if (userId == null) {
            return Result.fail("用户ID不能为空");
        }
        if (ObjectUtil.isNull(pageNum)) {
            pageNum = 1;
        }
        if (ObjectUtil.isNull(pageSize)) {
            pageSize = 10;
        }
        // 开始分页
        PageHelper.startPage(pageNum, pageSize);
        // 查询数据库
        List<JobPO> jobList = jobMapper.selectList(new QueryWrapper<JobPO>().eq("user_id", userId));

        // 如果查询结果为空，返回空列表
        if (jobList == null || jobList.isEmpty()) {
            return Result.success();
        }

        // 使用 Stream API 将 JobPO 转换为 JobDTO
        List<JobDTO> jobDTOS = jobList.stream()
                .map(jobPO -> toJobDTO(jobPO, areaMapper))
                .collect(Collectors.toList());
        PageInfo<JobDTO> pageInfo = new PageInfo<>(jobDTOS);
        // 创建 PageResult 对象
        PageResult<JobDTO> pageResult = new PageResult<>(pageInfo);
        // 返回结果
        return Result.success(pageResult);
    }

    @Override
    public Result getJobById(Long id) {
        try {
            // 1. 参数校验
            if (id == null) {
                log.warn("参数校验失败，ID不能为空");
                return Result.fail("ID不能为空");
            }

            // 2. 根据ID查询职位信息
            JobPO jobPO = jobMapper.selectById(id);
            if (jobPO == null) {
                LogUtil.info(String.format("未找到职位信息，ID: %d", id));
                return Result.fail("未找到职位信息");
            }

            // 3. 属性拷贝
            JobDTO jobDTO = toJobDTO(jobPO, areaMapper);

            // 4. 返回查询结果
            LogUtil.info(String.format("成功查询到职位信息，ID: %d", id));
            return Result.success(jobDTO);
        } catch (Exception e) {
            // 5. 捕获并处理异常
            LogUtil.info(String.format("查询职位信息异常，ID: %d %s", id, e));
            return Result.fail("查询职位信息失败，请稍后重试");
        }
    }

    @Override
    public Result getJobByUserId(Long userId) {
        try {
            // 1. 参数校验
            if (userId == null) {
                log.warn("参数校验失败，ID不能为空");
                return Result.fail("ID不能为空");
            }

            // 2. 根据ID查询职位信息
            List<JobPO> jobList = jobMapper.selectList(new QueryWrapper<JobPO>().eq("user_id", userId));
            // 如果查询结果为空，返回空列表
            if (jobList == null || jobList.isEmpty()) {
                return Result.success();
            }


            // 使用 Stream API 将 JobPO 转换为 JobDTO
            List<JobDTO> jobDTOS = jobList.stream()
                    .map(jobPO -> toJobDTO(jobPO, areaMapper))
                    .collect(Collectors.toList());

            // 4. 返回查询结果
            LogUtil.info(String.format("成功查询到职位信息，ID: %d", userId));
            return Result.success(jobDTOS);
        } catch (Exception e) {
            // 5. 捕获并处理异常
            LogUtil.info(String.format("查询职位信息异常，ID: %d %s", userId, e));
            return Result.fail("查询职位信息失败，请稍后重试");
        }
    }

    /**
     * 编辑职位
     *
     * @param jobVO
     * @return
     */
    @Override
    public Result editJob(JobVO jobVO) {
        // 1. 创建JobPO对象
        JobPO jobPO = new JobPO();

        // 2. 使用BeanUtils.copyProperties进行属性拷贝
        try {
            BeanUtils.copyProperties(jobVO, jobPO);
        } catch (Exception e) {
            // 处理属性拷贝过程中可能出现的异常
            log.error("属性拷贝失败", e);
            return Result.fail("更新失败，属性拷贝异常");
        }

        // 3. 更新数据库记录
        int updateCount = baseMapper.updateJob(jobPO);

        // 4. 根据更新结果返回相应的Result
        if (updateCount > 0) {
            return Result.success("更新成功");
        } else {
            return Result.fail("更新失败，记录不存在或未更改");
        }

    }

    @Override
    public Result getJobStatsLastSixMonths() {
        // 获取近六个月的起止日期
        YearMonth current = YearMonth.now();
        List<YearMonth> lastSixMonths = IntStream.rangeClosed(0, 5)
                .mapToObj(i -> current.minusMonths(5 - i)) // 从5个月前到当前月
                .collect(Collectors.toList());

        // 查询每个月的岗位数量
        List<Long> counts = lastSixMonths.stream()
                .map(month -> {
                    LocalDate startDate = month.atDay(1);
                    LocalDate endDate = month.atEndOfMonth();
                    return jobMapper.countByCreateTimeBetween(startDate, endDate);
                })
                .collect(Collectors.toList());
        return Result.success(counts);
    }

    @Override
    public Result searchJobsWithQuery(JobVO jobVO, Integer pageNum, Integer pageSize) {
        try {
            if (ObjectUtil.isNull(pageNum)) {
                pageNum = 1;
            }
            if (ObjectUtil.isNull(pageSize)) {
                pageSize = 10;
            }
            List<JobDTO> jobDTOList = jobMapper.filterJobs(jobVO);
            // 设置地区名称
            for (JobDTO jobDTO : jobDTOList) {
                String areaCode = jobDTO.getAreaCode();
                if (areaCode != null) {
                    String areaName = areaMapper.getAreaByCode(areaCode);
                    jobDTO.setAreaCode(areaName);
                }
                // 格式化薪资
                String minSalary = jobDTO.getMinSalary();
                String maxSalary = jobDTO.getMaxSalary();
                jobDTO.setSalary(formatSalary(minSalary, maxSalary));
            }

            PageInfo<JobDTO> pageInfo = new PageInfo<>(jobDTOList);
            // 创建 PageResult 对象
            PageResult<JobDTO> pageResult = new PageResult<>(pageInfo);
            // 3. 返回查询结果
            LogUtil.info(String.format("成功查询到 %d 条职位状态记录", jobDTOList.size()));
            return Result.success(pageResult);
        } catch (Exception e) {
            // 4. 捕获并处理异常
            log.error("查询职位状态列表异常", e);
            return Result.fail("查询职位状态列表失败，请稍后重试");
        }
    }


    /**
     * 将 JobPO 转换为 JobDTO，并填充额外字段（如地区名称和格式化薪资）。
     *
     * @param jobPO      职位PO对象
     * @param areaMapper 地区Mapper
     * @return 转换后的 JobDTO 对象
     */
    public static JobDTO toJobDTO(JobPO jobPO, AreaMapper areaMapper) {
        JobDTO jobDTO = new JobDTO();
        // 使用 BeanUtils 复制属性
        BeanUtils.copyProperties(jobPO, jobDTO);

        // 设置地区名称
        String areaCode = jobPO.getAreaCode();
        if (areaCode != null) {
            String areaName = areaMapper.getAreaByCode(areaCode);
            jobDTO.setAreaCode(areaName);
        }

        // 格式化薪资
        String minSalary = jobPO.getMinSalary();
        String maxSalary = jobPO.getMaxSalary();
        jobDTO.setSalary(formatSalary(minSalary, maxSalary));

        return jobDTO;
    }


    /**
     * 将 minSalary 和 maxSalary 拼接成 "min-max salary" 格式
     *
     * @param minSalary 最低薪资
     * @param maxSalary 最高薪资
     * @return 拼接后的字符串
     */
    public static String formatSalary(String minSalary, String maxSalary) {
        return minSalary + "-" + maxSalary;
    }
}
